package com.dhcc.sds.task;

import cn.hutool.core.date.DateTime;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.dhcc.cdc.busi.entity.*;
import com.dhcc.cdc.busi.service.*;
import com.dhcc.cdc.sys.cache.config.CdcConfigCache;
import com.dhcc.cdc.sys.service.IConfigurationService;
import com.dhcc.cdc.sys.service.IDictionaryService;
import com.dhcc.core.framework.util.CommonUtil;
import com.dhcc.core.framework.util.SpringContextHolder;
import com.dhcc.sds.base.entity.SdsExpressEntity;
import com.dhcc.sds.base.entity.SdsQcentityEntity;
import com.dhcc.sds.base.entity.SdsQcentityRuleEntity;
import com.dhcc.sds.base.function.GetEntrySrv;
import com.dhcc.sds.base.service.ISdsCommonService;
import com.dhcc.sds.base.service.ISdsExpressService;
import com.dhcc.sds.base.service.ISdsQcentityRuleService;
import com.dhcc.sds.base.service.ISdsQcentityService;
import com.dhcc.sds.busi.dto.SdsQcFormItemDto;
import com.dhcc.sds.busi.entity.SdsQcincaseEntity;
import com.dhcc.sds.busi.entity.SdsQcincaseOperlogEntity;
import com.dhcc.sds.busi.service.*;
import com.dhcc.sds.custom.entity.SdsCusMrlistEntity;
import com.dhcc.sds.custom.entity.SdsCusMrlistOperlogEntity;
import com.dhcc.sds.custom.service.ISdsCusMrlistOperlogService;
import com.dhcc.sds.custom.service.ISdsCusMrlistService;
import com.dhcc.sds.util.DateUtil;
import com.dhcc.sds.ws.dhcmessage.DHCMessageServiceLocator;
import com.dhcc.sds.ws.dhcmessage.DHCMessageServiceSoap;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.util.StringUtils;

import javax.xml.rpc.ServiceException;
import java.lang.reflect.Method;
import java.rmi.RemoteException;
import java.text.DecimalFormat;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

/**
 * @Description:单病种出院病例自动筛查
 * @ClassName: QCTask
 * @date:2021年5月28日 下午3:45:16
 * @author: zhangdc
 */
@Service("qcTask")
public class QcTask {

    @Autowired
    private ICdcEpisodeService cdcEpisodeService;

    @Autowired
    private ISdsQcincaseService sdsQcincaseService;

    @Autowired
    private IDictionaryService dictionaryService;

    @Autowired
    private ISdsQcentityService sdsQcentityService;

    @Autowired
    private ISdsQcentityRuleService sdsQcentityRuleService;

    @Autowired
    private ISdsExpressService sdsExpressService;

    @Autowired
    private ISdsQcincaseOperlogService sdsQcincaseOperlogService;

    @Autowired
    private ISdsCusMrlistOperlogService sdsCusMrlistOperlogService;

    @Autowired
    private PlatformTransactionManager platformTransactionManager;

    @Autowired
    private ISdsQcfitemExecresultService sdsQcfitemExecresultService;

    @Autowired
    private ICdcLabSetService cdcLabSetService;

    @Autowired
    private ICdcOrdexecService cdcOrdexecService;

    @Autowired
    private ICdcLabOrderService cdcLabOrderService;

    @Autowired
    private ICdcLabResultService cdcLabResultService;

    @Autowired
    private ICdcLabEntryService cdcLabEntryService;

    @Autowired
    private IConfigurationService configurationService;

    @Autowired
    private ISdsQcFormShowService sdsQcFormShowService;

    @Autowired
    private ISdsQcincaseDataService sdsQcincaseDataService;

    @Autowired
    private GetEntrySrv getEntrySrv;

    @Autowired
    private ICdcTransferService cdcTransferService;

    @Autowired
    private ICdcLocationService cdcLocationService;

    @Autowired
    private ISdsCommonService sdsCommonService;

    @Autowired
    private ISdsCusMrlistService sdsCusMrlistService;

    protected final static Logger logger = LoggerFactory.getLogger(QcTask.class);

    @Value("${sys.dhcHisCacheIp}")
    private String dhcHisCacheIp;                    //获取his发布的接口地址

    @Value("${sys.dhcHisCachePath}")
    private String dhcHisCachePath;

    @Value("${sys.dhcHisInterfaceHead}") //东华HIS对外接口是否有head验证 true 有 false无
    private boolean dhcHisInterfaceHead;

    double all = 1;
    Double cur = (double) 0;
    Double cur1 = (double) 0;
    /**特殊病种*/
    private static final int SPECIFIC = 1;
    /**非特殊病种*/
    private static final int NO_SPECIFIC = 0;
    /**自定义病种*/
    private static final int CUSTOM = 2;

    /**
     * 通过出院开始结束日期，获取单病种病例
     */
    public void autoTaskForMrList() throws Exception {
        String yesterday = DateUtil.getDayDate(-1, "yyyy-MM-dd");//注意这个MM不要写成小写
        String aFromDate = yesterday + " 00:00:00";
        String aToDate = yesterday + " 23:59:59";
        //多线程开始判定每个病例
        //线程仓库
        ExecutorService analysisDataPools = Executors.newFixedThreadPool(10);//分析数据线程池
        //取完成编目的患者
        Map<String, Object> params = new HashMap<>();
        params.put("startDate", aFromDate);
        params.put("endDate", aToDate);
        List<CdcEpisodeEntity> fpCodingAdmsByDate = cdcEpisodeService.getFPCodingAdmsByDate(params);
        all = fpCodingAdmsByDate.size();
        cur = (double) 0;
        for (CdcEpisodeEntity cdcEpisodeEntity : fpCodingAdmsByDate) {
            analysisDataPools.execute(new AnalysisData(cdcEpisodeEntity.getId(), null));//分析数据
            //checkSDByAdm(cdcEpisodeEntity.getId());
        }
        analysisDataPools.shutdown();
    }

    /**
     * 通过出院开始结束日期，获取自定义病种病例
     */
    public void autoTaskForCusMrList() throws Exception {
        String yesterday = DateUtil.getDayDate(-1, "yyyy-MM-dd");//注意这个MM不要写成小写
        String aFromDate = yesterday + " 00:00:00";
        String aToDate = yesterday + " 23:59:59";
        //多线程开始判定每个病例
        //线程仓库
        ExecutorService analysisDataPools = Executors.newFixedThreadPool(10);//分析数据线程池
        //取完成编目的患者
        Map<String, Object> params = new HashMap<>();
        params.put("startDate", aFromDate);
        params.put("endDate", aToDate);
        List<CdcEpisodeEntity> fpCodingAdmsByDate = cdcEpisodeService.getFPCodingAdmsByDate(params);
        all = fpCodingAdmsByDate.size();
        cur1 = (double) 0;
        for (CdcEpisodeEntity cdcEpisodeEntity : fpCodingAdmsByDate) {
            analysisDataPools.execute(new AnalysisCusData(cdcEpisodeEntity.getId(), null));//分析数据
            //checkSDByAdm(cdcEpisodeEntity.getId());
        }
        analysisDataPools.shutdown();
    }


    /**
     * 根据就诊号进行入组规则筛查
     * @param aEpisodeID 患者就诊号
     * @param entityIds 参与筛查病种ID串
     */
    public void checkSDByAdm(Long aEpisodeID, String entityIds) throws Exception {
        //通过就诊id获取就诊对象
        CdcEpisodeEntity cdcEpisodeEntity = cdcEpisodeService.selectById(aEpisodeID);
        if (!StringUtils.isEmpty(cdcEpisodeEntity)) {
            Wrapper<SdsQcincaseEntity> mrWpr = new EntityWrapper<>();
            mrWpr.eq("episode_id", aEpisodeID).ne("state", "O");
            List<SdsQcincaseEntity> mrList = sdsQcincaseService.selectList(mrWpr);
            //是否支持【特定病种和普通病种重复上报】
            String checkFlag = CdcConfigCache.me().getValueByKey("SDS", "checkSpecificEntity");
            if (CommonUtil.equals(checkFlag, "Y")){
                //获取特殊病种列表
                List<SdsQcentityEntity> specificEntities = getSpecificEntity();
                //若已经存在有效非特定病种表单,则只进行特殊病种筛查
                for (SdsQcincaseEntity sdsQcincaseEntity : mrList) {
                    SdsQcentityEntity sdsQcentityEntity = new SdsQcentityEntity();
                    sdsQcentityEntity.setId(sdsQcincaseEntity.getEntityId());
                    sdsQcentityEntity = sdsQcentityService.selectById(sdsQcentityEntity);
                    if (!specificEntities.contains(sdsQcentityEntity)){
                        checkSDSpecific(cdcEpisodeEntity,entityIds);
                        return;
                    }
                }
            }else {
                ///如果患者已经存在有效的单病种表单，则退出入组判断
                if (CommonUtil.isNotEmpty(mrList)) {
                    return;
                }
            }
            //遍历已经开展的质控病种
            List<SdsQcentityEntity> qcentityEntities;
            if (CommonUtil.equals(checkFlag, "Y")){
                //除特定病种外的病种
                qcentityEntities = specificEntityFilter(entityIds,NO_SPECIFIC);
            }else {
                Long entityTypeId = sdsCommonService.getDictId("QcentityType","Up");
                Wrapper<SdsQcentityEntity> wpr = new EntityWrapper<>();
                wpr.eq("entity_type_id",entityTypeId).ne("is_active", 0).in("id", entityIds).orderBy("ind_no"); // 非作废病种且按照排序码排序
                qcentityEntities = sdsQcentityService.selectList(wpr);
            }
            //进行病种筛查
            if (qcentityEntities != null) {
                checkSD(cdcEpisodeEntity,qcentityEntities,NO_SPECIFIC);
            }
            if (CommonUtil.equals(checkFlag, "Y")) {
                //特定病种筛查
                checkSDSpecific(cdcEpisodeEntity, entityIds);
            }
        }

    }

    /**
     * 检查入组特殊病种(DVT、VTE、PIP)
     * @author yhw
     * @date 2024/6/18
     * @param cdcEpisodeEntity 患者信息实体
     * @param entityIds 参与筛查病种ID串
     * @throws Exception NoSuchMethodException, ClassNotFoundException, InvocationTargetException, IllegalAccessException
     */
    public void checkSDSpecific(CdcEpisodeEntity cdcEpisodeEntity, String entityIds) throws Exception {
        //获取特殊病种
        List<SdsQcentityEntity> specificEntities = specificEntityFilter(entityIds, SPECIFIC);
        Wrapper<SdsQcincaseEntity> mrWpr = new EntityWrapper<>();
        mrWpr.eq("episode_id", cdcEpisodeEntity.getId()).ne("state", "O");
        List<SdsQcincaseEntity> mrList = sdsQcincaseService.selectList(mrWpr);
        if (CommonUtil.isEmpty(specificEntities)) return;
        //排除已入组的特殊病种
        for (SdsQcincaseEntity qcincaseEntity : mrList) {
            specificEntities.removeIf(specificEntity ->
                    specificEntity.getId().equals(qcincaseEntity.getEntityId()));
        }
        //进行病种筛查
        checkSD(cdcEpisodeEntity,specificEntities,SPECIFIC);
    }



    /**
     * 根据入组规则进行筛查
     * @param cdcEpisodeEntity 患者信息实体
     * @param qcentityEntities 参与筛查病种实体集合
     * @param specificMark 是否特定病种标记
     * @throws Exception NoSuchMethodException, ClassNotFoundException, InvocationTargetException, IllegalAccessException
     */
    private void checkSD(CdcEpisodeEntity cdcEpisodeEntity, List<SdsQcentityEntity> qcentityEntities ,int specificMark) throws Exception {
        Long aEpisodeID = cdcEpisodeEntity.getId();
        Long mrListID = null;
        String entityDesc = "";
        Date inDate = null;
        Date nowDate = new Date();
        for (SdsQcentityEntity sdsQcentityEntity : qcentityEntities) {
            if (!StringUtils.isEmpty(mrListID) && specificMark == NO_SPECIFIC) {
                //已入病种，退出判断
                break;
            }
            //按照关联科室过滤患者
            String linkDept = sdsQcentityEntity.getLinkDept();
            if (CommonUtil.isNotEmpty(linkDept)) {
                Wrapper<CdcTransferEntity> transferOutCCU = new EntityWrapper<>();
                transferOutCCU.eq("episode_id", aEpisodeID).eq("is_active", 1);
                List<CdcTransferEntity> cdcTransferList = cdcTransferService.selectList(transferOutCCU);
                boolean deptFlag = false;
                b:
                for (String deptCode : linkDept.split(",")) {
                    for (CdcTransferEntity cdcTransferEntity : cdcTransferList) {
                        if (!StringUtils.isEmpty(cdcTransferEntity.getTranBedId())) {
                            //只检索转科记录
                            continue;
                        }
                        CdcLocationEntity locationEntity = cdcLocationService.selectById(cdcTransferEntity.getTranLocId());
                        if (!StringUtils.isEmpty(locationEntity)) {
                            if (CommonUtil.equals(deptCode, locationEntity.getXcode())) {
                                deptFlag = true;
                                break b;
                            }
                        }
                    }
                }
                if (!deptFlag) {
                    continue;
                }
            }

            //防止排除的病种再次筛查
            Wrapper<SdsQcincaseEntity> wrapper = new EntityWrapper<>();
            wrapper.eq("episode_id", aEpisodeID)
                    .eq("entity_id", sdsQcentityEntity.getId())
                    .eq("state", "O");
            List<SdsQcincaseEntity> list = sdsQcincaseService.selectList(wrapper);
            if (!list.isEmpty()) {
                continue;
            }
            Map<String, Object> map2 = new HashMap<>();
            map2.put("entityId", sdsQcentityEntity.getId());
            List<SdsQcentityRuleEntity> qcentityRuleEntities = sdsQcentityRuleService.list(map2);
            //准入规则
            List<SdsQcentityRuleEntity> admits = new ArrayList<>();
            //排除规则
            List<SdsQcentityRuleEntity> exclude = new ArrayList<>();
            for (SdsQcentityRuleEntity sdsQcentityRuleEntity : qcentityRuleEntities) {
                if ((!Objects.equals(1, sdsQcentityRuleEntity.getIsActive()))
                        || (Objects.equals(1, sdsQcentityRuleEntity.getIsOnly()))) {
                    continue;
                }
                if (Objects.equals("1", sdsQcentityRuleEntity.getRuleType())) {
                    admits.add(sdsQcentityRuleEntity);
                } else {
                    exclude.add(sdsQcentityRuleEntity);
                }
            }
            //有准入配置，才进行入组判断
            String ret = "";
            StringBuilder ruleId = new StringBuilder();
            if (!admits.isEmpty()) {
                //Param2:判断且伴为同一组的准入规则，排序相同的为同一组
                //String param2 = sdsQcentityRuleEntity.getParam2();
                //按Param2进行分组
                Map<String, List<SdsQcentityRuleEntity>> collect = admits.stream().collect(Collectors.groupingBy(p -> p.getParam2() == null ? "" : p.getParam2(), Collectors.toList()));
                b:
                for (String param2 : collect.keySet()) {
                    List<SdsQcentityRuleEntity> sdsQcentityRuleEntities = collect.get(param2);
                    //每一组ruleId重置
                    ruleId = new StringBuilder();
                    for (SdsQcentityRuleEntity sdsQcentityRuleEntity : sdsQcentityRuleEntities) {
                        ret = "N";
                        SdsExpressEntity sdsExpressEntity = sdsExpressService.selectById(sdsQcentityRuleEntity.getExpressId());
                        if (!StringUtils.isEmpty(sdsExpressEntity)) {
                            Class<?> c = Class.forName("com.dhcc.sds.base.function.GetEntrySrv");
                            GetEntrySrv getEntrySrv = SpringContextHolder.getBean("getEntrySrv");
                            Method method = c.getMethod(sdsExpressEntity.getExpress(), Long.class, String.class);
                            ret = (String) method.invoke(getEntrySrv, aEpisodeID, sdsQcentityRuleEntity.getParam());
                            if (!Objects.equals("Y", ret)) {
                                continue b;
                            } else {
                                //记录ruleId
                                ruleId.append(sdsQcentityRuleEntity.getId()).append(",");
                            }
                        }
                    }
                    if (Objects.equals("Y", ret)) {
                        //多个准入，并行满足一个跳出
                        break;
                    }
                }
                DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
                definition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
                TransactionStatus transactionStatus = platformTransactionManager.getTransaction(definition);
                try {
                    if (Objects.equals("Y", ret)) {
                        //如果满足第一准入条件，直接进入单病种列表
                        SdsQcincaseEntity sdsQcincaseEntity = new SdsQcincaseEntity();
                        sdsQcincaseEntity.setEpisodeId(aEpisodeID);
                        sdsQcincaseEntity.setEntityId(sdsQcentityEntity.getId());
                        sdsQcincaseEntity.setInUserId(cdcEpisodeEntity.getAdmDoctorId());
                        sdsQcincaseEntity.setInLocId(cdcEpisodeEntity.getAdmLocId());
                        sdsQcincaseEntity.setInWardId(cdcEpisodeEntity.getAdmWardId());
                        sdsQcincaseEntity.setInDate(nowDate);
                        sdsQcincaseEntity.setInTime(nowDate);
                        sdsQcincaseEntity.setState("I");
                        sdsQcincaseEntity.setGroupStatus("SysRec");
                        sdsQcincaseEntity.setFillingStatus("NotFilled");
                        sdsQcincaseEntity.setReportStatus("NotUp");
                        sdsQcincaseEntity.setIntheMoment("D");
                        boolean insert = sdsQcincaseService.insert(sdsQcincaseEntity);
                        if (insert) {
                            //增加病历状态记录
                            SdsQcincaseOperlogEntity sdsQcincaseOperlogEntity = new SdsQcincaseOperlogEntity();
                            sdsQcincaseOperlogEntity.setInCaseId(sdsQcincaseEntity.getId());
                            sdsQcincaseOperlogEntity.setOperState("I");
                            sdsQcincaseOperlogEntity.setOperUser("系统");
                            sdsQcincaseOperlogEntity.setOperDate(nowDate);
                            sdsQcincaseOperlogEntity.setOperReason(ruleId.toString());
                            boolean insert1 = sdsQcincaseOperlogService.insert(sdsQcincaseOperlogEntity);
                            if (insert1) {
                                mrListID = sdsQcincaseEntity.getId();
                                entityDesc = sdsQcentityEntity.getBtDesc();
                                inDate = sdsQcincaseEntity.getInDate();
                            }
                        }
                        //通过统一的重复入院和出院标准进行排除
                        String delReason = getEntrySrv.unifyCheck(aEpisodeID, sdsQcentityEntity.getAbbrev());
                        String ruleIDStr = "";
                        if (StringUtils.isEmpty(delReason) && !exclude.isEmpty()) {
                            //按Param2进行分组
                            Map<String, List<SdsQcentityRuleEntity>> excludeCollect = exclude.stream().collect(Collectors.groupingBy(p -> CommonUtil.isEmpty(p.getParam2()) ? p.getId().toString() : p.getParam2(), Collectors.toList()));
                            c:for (String param2 : excludeCollect.keySet()) {
                                List<SdsQcentityRuleEntity> sdsQcentityRuleEntities = excludeCollect.get(param2);
                                //每一组ruleId重置
                                ruleIDStr = "";
                                //对于符合准入条件，且有排除配置的病例，做自动排除判断
                                for (SdsQcentityRuleEntity sdsQcentityRuleEntity : sdsQcentityRuleEntities) {
                                    String ruleDesc = sdsQcentityRuleEntity.getRuleDesc();
                                    // 此类排除条件已在上面统一处理，这里直接跳过
                                    if (ruleDesc.contains("24小时内") || ruleDesc.contains("日内重复入院")) {
                                        continue;
                                    }
                                    SdsExpressEntity sdsExpressEntity = sdsExpressService.selectById(sdsQcentityRuleEntity.getExpressId());
                                    if (!StringUtils.isEmpty(sdsExpressEntity)) {
                                        Class<?> aClass = Class.forName("com.dhcc.sds.base.function.GetEntrySrv");
                                        GetEntrySrv expressFunction = (GetEntrySrv) aClass.newInstance();
                                        Method method = aClass.getMethod(sdsExpressEntity.getExpress(), Long.class, String.class);
                                        ret = (String) method.invoke(expressFunction, aEpisodeID, sdsQcentityRuleEntity.getParam());

                                        if (!Objects.equals("Y", ret)) {
                                            continue c;
                                        } else {
                                            //记录ruleId
                                            ruleIDStr += sdsQcentityRuleEntity.getId() + ",";
                                        }
                                    }
                                }
                                if (Objects.equals("Y", ret)) {
                                    //多个排除，并行满足一个跳出
                                    break;
                                }
                            }
                        }
                        if (!StringUtils.isEmpty(delReason) || !StringUtils.isEmpty(ruleIDStr)) {
                            sdsQcincaseEntity.setOutDate(nowDate);
                            sdsQcincaseEntity.setOutTime(nowDate);
                            sdsQcincaseEntity.setOutDocId(cdcEpisodeEntity.getAdmDoctorId());
                            sdsQcincaseEntity.setState("O");
                            boolean b = sdsQcincaseService.updateById(sdsQcincaseEntity);
                            if (b) {
                                SdsQcincaseOperlogEntity sdsQcincaseOperlogEntity = new SdsQcincaseOperlogEntity();
                                sdsQcincaseOperlogEntity.setInCaseId(sdsQcincaseEntity.getId());
                                sdsQcincaseOperlogEntity.setOperState("O");
                                sdsQcincaseOperlogEntity.setOperUser("系统");
                                sdsQcincaseOperlogEntity.setOperDate(nowDate);
                                sdsQcincaseOperlogEntity.setOperReason(ruleIDStr);
                                sdsQcincaseOperlogEntity.setOperResume(delReason);
                                boolean insert1 = sdsQcincaseOperlogService.insert(sdsQcincaseOperlogEntity);
                                if (insert1) {
                                    mrListID = null;
                                    entityDesc = "";
                                    inDate = null;
                                }
                            }
                        }
                    }
                } catch (ClassNotFoundException | InstantiationException e) {
                    e.printStackTrace();
                    platformTransactionManager.rollback(transactionStatus);
                }
                platformTransactionManager.commit(transactionStatus);
            }
        }
        // 是否向临床推送消息
        String sendFlag = CdcConfigCache.me().getValueByKey("SDS", "ClinicalSendMessage");
        if (CommonUtil.equals(sendFlag, "Y")) {
            // 如果入组，往临床推送消息提醒
            if (mrListID != null) {
                this.sendMessage2His(aEpisodeID, mrListID, entityDesc, inDate);
            }
        }
        //如果存在门户数据采集程序，更新维度数据
        sdsQcincaseDataService.updatePortalData(mrListID);
    }

    /**
     * 检查入组自定义病种
     * @author yhw
     * @date 2024/6/21
     * @param aEpisodeID 患者信息ID
     * @param entityIds 参与筛查病种ID串
     * @throws Exception NoSuchMethodException, ClassNotFoundException, InvocationTargetException, IllegalAccessException
     */
    public void checkSDCustom(Long aEpisodeID, String entityIds) throws Exception {
        CdcEpisodeEntity cdcEpisodeEntity = cdcEpisodeService.selectById(aEpisodeID);
        //获取特殊病种
        Long entityTypeId = sdsCommonService.getDictId("QcentityType","Custom");
        Wrapper<SdsQcentityEntity> wpr = new EntityWrapper<>();
        wpr.eq("entity_type_id",entityTypeId).ne("is_active", 0).in("id", entityIds).orderBy("ind_no"); // 非作废病种且按照排序码排序
        List<SdsQcentityEntity> customEntities = sdsQcentityService.selectList(wpr);

        Wrapper<SdsCusMrlistEntity> mrWpr = new EntityWrapper<>();
        mrWpr.eq("episode_id", cdcEpisodeEntity.getId()).ne("state", "O");
        List<SdsCusMrlistEntity> mrList = sdsCusMrlistService.selectList(mrWpr);
        if (CommonUtil.isEmpty(customEntities)) return;
        //排除已入组的自定义病种
        for (SdsCusMrlistEntity cusMrlistEntity : mrList) {
            customEntities.removeIf(customEntity ->
                    customEntity.getId().equals(cusMrlistEntity.getEntityId()));
        }
        //TODO 进行病种筛查
        Long mrListID = null;
        String entityDesc = "";
        Date inDate = null;
        Date nowDate = new Date();
        for (SdsQcentityEntity sdsQcentityEntity : customEntities) {
            //按照关联科室过滤患者
            String linkDept = sdsQcentityEntity.getLinkDept();
            if (CommonUtil.isNotEmpty(linkDept)) {
                Wrapper<CdcTransferEntity> transferOutCCU = new EntityWrapper<>();
                transferOutCCU.eq("episode_id", aEpisodeID).eq("is_active", 1);
                List<CdcTransferEntity> cdcTransferList = cdcTransferService.selectList(transferOutCCU);
                boolean deptFlag = false;
                b:
                for (String deptCode : linkDept.split(",")) {
                    for (CdcTransferEntity cdcTransferEntity : cdcTransferList) {
                        if (!StringUtils.isEmpty(cdcTransferEntity.getTranBedId())) {
                            //只检索转科记录
                            continue;
                        }
                        CdcLocationEntity locationEntity = cdcLocationService.selectById(cdcTransferEntity.getTranLocId());
                        if (!StringUtils.isEmpty(locationEntity)) {
                            if (CommonUtil.equals(deptCode, locationEntity.getXcode())) {
                                deptFlag = true;
                                break b;
                            }
                        }
                    }
                }
                if (!deptFlag) {
                    continue;
                }
            }
            //防止排除的病种再次筛查
            Wrapper<SdsCusMrlistEntity> wrapper = new EntityWrapper<>();
            wrapper.eq("episode_id", aEpisodeID)
                    .eq("entity_id", sdsQcentityEntity.getId())
                    .eq("state", "O");
            List<SdsCusMrlistEntity> list = sdsCusMrlistService.selectList(wrapper);
            if (!list.isEmpty()) {
                continue;
            }
            Map<String, Object> map2 = new HashMap<>();
            map2.put("entityId", sdsQcentityEntity.getId());
            List<SdsQcentityRuleEntity> qcentityRuleEntities = sdsQcentityRuleService.list(map2);
            //准入规则
            List<SdsQcentityRuleEntity> admits = new ArrayList<>();
            //排除规则
            List<SdsQcentityRuleEntity> exclude = new ArrayList<>();
            for (SdsQcentityRuleEntity sdsQcentityRuleEntity : qcentityRuleEntities) {
                if ((!Objects.equals(1, sdsQcentityRuleEntity.getIsActive()))
                        || (Objects.equals(1, sdsQcentityRuleEntity.getIsOnly()))) {
                    continue;
                }
                if (Objects.equals("1", sdsQcentityRuleEntity.getRuleType())) {
                    admits.add(sdsQcentityRuleEntity);
                } else {
                    exclude.add(sdsQcentityRuleEntity);
                }
            }
            //有准入配置，才进行入组判断
            String ret = "";
            StringBuilder ruleId = new StringBuilder();
            if (!admits.isEmpty()) {
                //Param2:判断且伴为同一组的准入规则，排序相同的为同一组
                //String param2 = sdsQcentityRuleEntity.getParam2();
                //按Param2进行分组
                Map<String, List<SdsQcentityRuleEntity>> collect = admits.stream().collect(Collectors.groupingBy(p -> p.getParam2() == null ? "" : p.getParam2(), Collectors.toList()));
                b:
                for (String param2 : collect.keySet()) {
                    List<SdsQcentityRuleEntity> sdsQcentityRuleEntities = collect.get(param2);
                    //每一组ruleId重置
                    ruleId = new StringBuilder();
                    for (SdsQcentityRuleEntity sdsQcentityRuleEntity : sdsQcentityRuleEntities) {
                        ret = "N";
                        SdsExpressEntity sdsExpressEntity = sdsExpressService.selectById(sdsQcentityRuleEntity.getExpressId());
                        if (!StringUtils.isEmpty(sdsExpressEntity)) {
                            Class<?> c = Class.forName("com.dhcc.sds.base.function.GetEntrySrv");
                            GetEntrySrv getEntrySrv = SpringContextHolder.getBean("getEntrySrv");
                            Method method = c.getMethod(sdsExpressEntity.getExpress(), Long.class, String.class);
                            ret = (String) method.invoke(getEntrySrv, aEpisodeID, sdsQcentityRuleEntity.getParam());
                            if (!Objects.equals("Y", ret)) {
                                continue b;
                            } else {
                                //记录ruleId
                                ruleId.append(sdsQcentityRuleEntity.getId()).append(",");
                            }
                        }
                    }
                    if (Objects.equals("Y", ret)) {
                        //多个准入，并行满足一个跳出
                        break;
                    }
                }
                DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
                definition.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
                TransactionStatus transactionStatus = platformTransactionManager.getTransaction(definition);
                try {
                    if (Objects.equals("Y", ret)) {
                        //如果满足第一准入条件，直接进入单病种列表
                        SdsCusMrlistEntity cusMrlistEntity = new SdsCusMrlistEntity();
                        cusMrlistEntity.setEpisodeId(aEpisodeID);
                        cusMrlistEntity.setEntityId(sdsQcentityEntity.getId());
                        cusMrlistEntity.setInUserId(cdcEpisodeEntity.getAdmDoctorId());
                        cusMrlistEntity.setInLocId(cdcEpisodeEntity.getAdmLocId());
                        cusMrlistEntity.setInWardId(cdcEpisodeEntity.getAdmWardId());
                        cusMrlistEntity.setInDate(nowDate);
                        cusMrlistEntity.setInTime(nowDate);
                        cusMrlistEntity.setState("I");
                        cusMrlistEntity.setGroupStatus("SysRec");
                        cusMrlistEntity.setIntheMoment("D");
                        boolean insert = sdsCusMrlistService.insert(cusMrlistEntity);
                        if (insert) {
                            //增加病历状态记录
                            SdsCusMrlistOperlogEntity cusMrlistOperlogEntity = new SdsCusMrlistOperlogEntity();
                            cusMrlistOperlogEntity.setInCaseId(cusMrlistEntity.getId());
                            cusMrlistOperlogEntity.setOperState("I");
                            cusMrlistOperlogEntity.setOperUser("系统");
                            cusMrlistOperlogEntity.setOperDate(nowDate);
                            cusMrlistOperlogEntity.setOperReason(ruleId.toString());
                            boolean insert1 = sdsCusMrlistOperlogService.insert(cusMrlistOperlogEntity);
                            if (insert1) {
                                mrListID = cusMrlistEntity.getId();
                                entityDesc = sdsQcentityEntity.getBtDesc();
                                inDate = cusMrlistEntity.getInDate();
                            }
                        }

                        //通过统一的重复入院和出院标准进行排除
                        String delReason = getEntrySrv.unifyCheck(aEpisodeID, sdsQcentityEntity.getAbbrev());
                        String ruleIDStr = "";
                        if (StringUtils.isEmpty(delReason) && !exclude.isEmpty()) {
                            //对于符合准入条件，且有排除配置的病例，做自动排除判断
                            for (SdsQcentityRuleEntity sdsQcentityRuleEntity : exclude) {
                                String ruleDesc = sdsQcentityRuleEntity.getRuleDesc();
                                // 此类排除条件已在上面统一处理，这里直接跳过
                                if (ruleDesc.contains("24小时内") || ruleDesc.contains("重复入院")) {
                                    continue;
                                }
                                SdsExpressEntity sdsExpressEntity = sdsExpressService.selectById(sdsQcentityRuleEntity.getExpressId());
                                if (!StringUtils.isEmpty(sdsExpressEntity)) {
                                    Class<?> aClass = Class.forName("com.dhcc.sds.base.function.GetEntrySrv");
                                    GetEntrySrv expressFunction = (GetEntrySrv) aClass.newInstance();
                                    Method method = aClass.getMethod(sdsExpressEntity.getExpress(), Long.class, String.class);
                                    ret = (String) method.invoke(expressFunction, aEpisodeID, sdsQcentityRuleEntity.getParam());

                                    if (Objects.equals("Y", ret)) {
                                        ruleIDStr = sdsQcentityRuleEntity.getId() + "";
                                        break;
                                    }
                                }
                            }
                        }
                        if (!StringUtils.isEmpty(delReason) || !StringUtils.isEmpty(ruleIDStr)) {
                            cusMrlistEntity.setOutDate(nowDate);
                            cusMrlistEntity.setOutTime(nowDate);
                            cusMrlistEntity.setOutDocId(cdcEpisodeEntity.getAdmDoctorId());
                            cusMrlistEntity.setState("O");
                            boolean b = sdsCusMrlistService.updateById(cusMrlistEntity);
                            if (b) {
                                SdsCusMrlistOperlogEntity cusMrlistOperlogEntity = new SdsCusMrlistOperlogEntity();
                                cusMrlistOperlogEntity.setInCaseId(cusMrlistEntity.getId());
                                cusMrlistOperlogEntity.setOperState("O");
                                cusMrlistOperlogEntity.setOperUser("系统");
                                cusMrlistOperlogEntity.setOperDate(nowDate);
                                cusMrlistOperlogEntity.setOperReason(ruleIDStr);
                                cusMrlistOperlogEntity.setOperResume(delReason);
                                boolean insert1 = sdsCusMrlistOperlogService.insert(cusMrlistOperlogEntity);
                                if (insert1) {
                                    mrListID = null;
                                    entityDesc = "";
                                    inDate = null;
                                }
                            }
                        }
                    }
                } catch (ClassNotFoundException | InstantiationException e) {
                    e.printStackTrace();
                    platformTransactionManager.rollback(transactionStatus);
                }
                platformTransactionManager.commit(transactionStatus);
            }
        }


        }

    /**
     * 对参与筛查的病种进行分类（根据特定病种标识）
     * @author yhw
     * @date 2024/6/18
     * @param entityIds 参与筛查病种ID串
     * @param specificMark 是否特定病种标识
     * @return 标识对应的筛查病种实体集合
     */
    private List<SdsQcentityEntity> specificEntityFilter (String entityIds,int specificMark){
        //重组选定入组病种信息
        Long entityTypeId = sdsCommonService.getDictId("QcentityType","Up");
        Wrapper<SdsQcentityEntity> wpr = new EntityWrapper<>();
        wpr.eq("entity_type_id",entityTypeId).ne("is_active", 0).in("id", entityIds).orderBy("ind_no"); // 非作废病种且按照排序码排序
        List<SdsQcentityEntity> qcentityEntities = sdsQcentityService.selectList(wpr);
        List<SdsQcentityEntity> specificEntities = getSpecificEntity();
        specificEntities.removeIf(specificEntity -> !qcentityEntities.remove(specificEntity));
        if (specificMark == SPECIFIC){
            return specificEntities;
        }else if (specificMark == NO_SPECIFIC){
            return qcentityEntities;
        }
        return null;
    }

    /**
     * 获取配置中特定病种实体
     * @author yhw
     * @date 2024/6/18
     * @return 特定病种实体类集合
     */
    private List<SdsQcentityEntity> getSpecificEntity(){
        List<SdsQcentityEntity> specificEntities = new ArrayList<>();
        String specificEntityStr = CdcConfigCache.me().getValueByKey("SDS", "SpecificEntity");
        String[] specificEntityAbbrev = specificEntityStr.split(",");
        for (String abbrev : specificEntityAbbrev) {
            Wrapper<SdsQcentityEntity> spcWpr = new EntityWrapper<>();
            spcWpr.eq("abbrev", abbrev);
            SdsQcentityEntity sdsQcentityEntity = sdsQcentityService.selectOne(spcWpr);
            specificEntities.add(sdsQcentityEntity);
        }
        return specificEntities;
    }

    /**
     * 推送消息
     *
     * @param patientId
     * @param mrListId
     * @param entityDesc
     * @param inDate
     */
    public void sendMessage2His(Long patientId, Long mrListId, String entityDesc, Date inDate) {
        // 获取his真实就诊号
        CdcEpisodeEntity paadm = cdcEpisodeService.selectById(patientId);
        String episodeId = paadm.getXcode();

        String context = "";
        String actionTypeCode = "";                //信息的动作类型代码  websys.DHCMessageActionType表的code字段值 回龙观1140
        String linkUrl = "";

        actionTypeCode = CdcConfigCache.me().getValueByKey("SDS", "MsgCodeHis");
        context = "<br>该出院患者是单病种入组患者，请及时填写病种上报信息。<br> 入组病种：" + entityDesc +
                "<br>入组日期：" + com.dhcc.core.framework.util.DateUtil.format(inDate, "yyyy-MM-dd HH:mm:ss");
        linkUrl = "dhc.sds.formFilling.message.csp?EpisodeID=" + episodeId + "&mrListId=" + mrListId;
        JSONObject job = new JSONObject();  //封装访问单病种填报页面的连接以及参数
        job.put("link", linkUrl);
        job.put("dialogWidth", "1400px");
        job.put("dialogHeight", "900px");
        job.put("messageCode", actionTypeCode);

        String fromUserRowId = "^单病种系统";        //信息发出人	SS_User->SSUSR_rowid, 如果消息发出人不在his人员表中,可直接传用户姓名。格式:"^Name"
        String ordItemId = null;                    //医嘱明细表Id			OE_OrdItem->OEORI_RowId  无为Null
        String toUserRowId = null;                //信息发给人			SS_User->SSUSR_rowid  强制把消息发给该用户
        String otherInfoJson = job.toString();    //其它业务相关对象    Json格式,一些其它信息,如link等{"link":"x.csp?type=a&id=1"}
        String locId = null;                        //接收消息科室ID 可以为null
        String effectiveDays = null;                //有效时间  为null 长久有效？
        String createLoc = null;                //创建消息的科室？
        String backCode = "";

        if (dhcHisInterfaceHead) {//如果his有head验证
            try {
                DHCMessageServiceLocator dhcLocator = new DHCMessageServiceLocator();
                DHCMessageServiceSoap soap = dhcLocator.getDHCMessageServiceSoap(dhcHisCacheIp, dhcHisCachePath);
                backCode = soap.send(
                        context,
                        actionTypeCode,
                        fromUserRowId,
                        episodeId,
                        ordItemId,
                        toUserRowId,
                        otherInfoJson,
                        locId,
                        effectiveDays,
                        createLoc);

            } catch (ServiceException e) {
                e.printStackTrace();
            } catch (RemoteException e) {
                e.printStackTrace();
            }
            logger.info("backCode:" + backCode);
        } else {
            String backInfo = "";
            JaxWsDynamicClientFactory dcf = JaxWsDynamicClientFactory.newInstance();
            Client client = dcf.createClient(dhcHisCacheIp + dhcHisCachePath + "/dhcservice.DHCMessageInterface.cls?WSDL=1");
            Object[] objects = new Object[11];
            try {
                objects = client.invoke("Send", context, actionTypeCode, fromUserRowId, episodeId, ordItemId,
                        toUserRowId, otherInfoJson, locId, effectiveDays, createLoc);
                backInfo = objects[0].toString();
            } catch (Exception e) {
                e.printStackTrace();
            }
            logger.info("backInfo:" + backInfo);
        }
    }

    /**
     * 手动执行入组筛查
     */
    public void manualMrList(Map<String, Object> params) throws Exception {

        //多线程开始判定每个病例
        //线程仓库
        ExecutorService analysisDataPools = Executors.newFixedThreadPool(10);//分析数据线程池
        //取完成编目的患者
        List<CdcEpisodeEntity> fpCodingAdmsByDate = cdcEpisodeService.getFPCodingAdmsByDate(params);
        all = fpCodingAdmsByDate.size();
        cur = (double) 0;
        for (CdcEpisodeEntity cdcEpisodeEntity : fpCodingAdmsByDate) {
            analysisDataPools.execute(new AnalysisData(cdcEpisodeEntity.getId(), params.get("entityId").toString()));//分析数据
            //checkSDByAdm(cdcEpisodeEntity.getId());
        }
        analysisDataPools.shutdown();
    }

    /**
     * 手动执行自定义病种入组筛查
     */
    public void manualCusMrList(Map<String, Object> params) throws Exception {

        //多线程开始判定每个病例
        //线程仓库
        ExecutorService analysisDataPools = Executors.newFixedThreadPool(10);//分析数据线程池
        //取完成编目的患者
        List<CdcEpisodeEntity> fpCodingAdmsByDate = cdcEpisodeService.getFPCodingAdmsByDate(params);
        all = fpCodingAdmsByDate.size();
        cur = (double) 0;
        for (CdcEpisodeEntity cdcEpisodeEntity : fpCodingAdmsByDate) {
            analysisDataPools.execute(new AnalysisCusData(cdcEpisodeEntity.getId(), params.get("entityId").toString()));//分析数据
            //checkSDByAdm(cdcEpisodeEntity.getId());
        }
        analysisDataPools.shutdown();
    }

    /**
     * 对入组病例进行初始化自动取值
     */
    public void autoTaskForInitMrList() {
        //多线程开始判定每个病例
        //线程仓库
        ExecutorService getValuePools = Executors.newFixedThreadPool(10);//分析数据线程池
        Wrapper<SdsQcincaseEntity> mrWpr = new EntityWrapper<>();
        mrWpr.eq("in_date", com.dhcc.core.framework.util.DateUtil.getDay()).in("state", "I", "Save");
        List<SdsQcincaseEntity> mrList = sdsQcincaseService.selectList(mrWpr);
        all = mrList.size();
        cur = (double) 0;
        for (SdsQcincaseEntity inCase : mrList) {
            getValuePools.execute(new GetValue(inCase.getId()));
            //sdsQcfitemExecresultService.execItemResult(inCase.getId());
        }
        getValuePools.shutdown();
    }

    /**
     * 手动执行自动取值
     */
    public void manualInitMrList(Map<String, Object> params) throws Exception {
        String startDate = params.get("startDate").toString();
        String endDate = params.get("endDate").toString();
        String patientId = params.get("patientId").toString();
        String deptId = params.get("deptId").toString();
        String entityId = params.get("entityId").toString();

        //多线程开始判定每个病例
        //线程仓库
        ExecutorService getValuePools = Executors.newFixedThreadPool(10);//分析数据线程池
        Wrapper<SdsQcincaseEntity> mrWpr = new EntityWrapper<>();
        mrWpr.in("state", "I", "Save");
        if (CommonUtil.isNotEmpty(startDate)) {
            mrWpr.ge("in_date", startDate);
        }
        if (CommonUtil.isNotEmpty(endDate)) {
            mrWpr.le("in_date", endDate);
        }
        if (CommonUtil.isNotEmpty(patientId)) {
            mrWpr.eq("episode_id", patientId);
        }
        if (CommonUtil.isNotEmpty(deptId)) {
            mrWpr.eq("in_loc_id", deptId);
        }
        if (CommonUtil.isNotEmpty(entityId)) {
            mrWpr.in("entity_id", entityId);
        }
        List<SdsQcincaseEntity> mrList = sdsQcincaseService.selectList(mrWpr);
        all = mrList.size();
        cur = (double) 0;
        ;
        for (SdsQcincaseEntity inCase : mrList) {
            getValuePools.execute(new GetValue(inCase.getId()));
            //sdsQcfitemExecresultService.execItemResult(inCase.getId());
        }
        getValuePools.shutdown();
    }


    /**
     * 更新t_cdc_ct_lab_order对照医嘱项关系
     */
    public void autoTaskForUpdateLabOrder() {
        //根据t_cdc_bs_lab_set重新生成检验医嘱和医嘱项对应关系（防止对应不正确情况）
        Wrapper<CdcLabSetEntity> labSetEntityWrapper = new EntityWrapper<>();
        labSetEntityWrapper.groupBy("ct_lab_order_id");
        List<CdcLabSetEntity> cdcLabSetEntities = cdcLabSetService.selectList(labSetEntityWrapper);
        for (CdcLabSetEntity labSetEntity : cdcLabSetEntities) {
            //根据医嘱执行记录获取医嘱项
            CdcOrdexecEntity cdcOrdexecEntity = cdcOrdexecService.selectById(labSetEntity.getOrderExecId());
            CdcLabOrderEntity labOrderEntity = cdcLabOrderService.selectById(labSetEntity.getCtLabOrderId());
            labOrderEntity.setOrderMastId(cdcOrdexecEntity.getOrderMastId());
            cdcLabOrderService.updateAllColumnById(labOrderEntity);
        }
    }


    /**
     * 带参数，可以只传一个日期，如2021-01-23。可以以#分隔传两个日期，如2021-01-23#2021-01-31
     * 通过入院开始结束日期，从业务数据中自动生成检验医嘱与检验项目的对应关系
     */
    public void autoTaskForUpdateLabEntry(String dateStr) {
        //根据检验报告检验结果生成检验医嘱与检验项目的对应关系
        List<CdcLabSetEntity> labSet = new ArrayList<>();

        if (StringUtils.isEmpty(dateStr)) {
            //查询所有
            Wrapper<CdcLabSetEntity> wrapper = new EntityWrapper<>();
            //wrapper.eq("is_sync", 0);
            wrapper.isNull("is_sync");
            labSet = cdcLabSetService.selectList(wrapper);
        } else {
            if (dateStr.contains("#")) {
                String aFromDate = dateStr.split("#")[0] + " 00:00:00";
                String aToDate = dateStr.split("#")[1] + " 23:59:59";
                labSet = cdcLabSetService.selectByAdmDate(aFromDate, aToDate);
            } else {
                if (DateUtil.isValidDate(dateStr)) {
                    String aFromDate = dateStr + " 00:00:00";
                    String aToDate = com.dhcc.core.framework.util.DateUtil.getTime();
                    labSet = cdcLabSetService.selectByAdmDate(aFromDate, aToDate);
                }
            }
        }

        for (CdcLabSetEntity cdcLabSetEntity : labSet) {
            List<Long> labItemIds = cdcLabResultService.selectLabItemsByLabVisit(cdcLabSetEntity.getLabVisitId());
            for (Long labItemId : labItemIds) {
                //增加检验医嘱和检验项目对照关系
                CdcLabEntryEntity cdcLabEntryEntity = cdcLabEntryService.selectByItemIdAndOrderId(labItemId, cdcLabSetEntity.getCtLabOrderId());
                if (StringUtils.isEmpty(cdcLabEntryEntity)) {
                    CdcLabEntryEntity cdcLabEntryEntity1 = new CdcLabEntryEntity();
                    cdcLabEntryEntity1.setLabItemId(labItemId);
                    cdcLabEntryEntity1.setLabOrderId(cdcLabSetEntity.getCtLabOrderId());
                    cdcLabEntryEntity1.setIsActive(1);
                    boolean insert = cdcLabEntryService.insert(cdcLabEntryEntity1);
                    if (insert) {
                        cdcLabSetEntity.setIsSync(1);
                        cdcLabSetService.updateById(cdcLabSetEntity);
                    }
                }
            }
        }

    }


    /**
     * 自动任务生成表单填报率
     */
    public void autoTaskForFormFillRate() {
        Wrapper<SdsQcincaseEntity> wpr = new EntityWrapper<>();
        wpr.eq("in_date", com.dhcc.core.framework.util.DateUtil.getDay()).in("state", "I", "Save");
        List<SdsQcincaseEntity> sdsQcincaseEntities = sdsQcincaseService.selectList(wpr);

        // 根据数据源配置自动取值
        for (SdsQcincaseEntity sdsQcincaseEntity : sdsQcincaseEntities) {
            try {
                sdsQcFormShowService.getItemResult(sdsQcincaseEntity.getId());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 手动表单填充率
     */
    public void manualFormFillRate(Map<String, Object> params) throws Exception {
        String startDate = params.get("startDate").toString();
        String endDate = params.get("endDate").toString();
        String patientId = params.get("patientId").toString();
        String deptId = params.get("deptId").toString();
        String entityId = params.get("entityId").toString();

        //多线程开始判定每个病例
        //线程仓库
        ExecutorService getValuePools = Executors.newFixedThreadPool(10);//分析数据线程池
        Wrapper<SdsQcincaseEntity> mrWpr = new EntityWrapper<>();
        mrWpr.in("state", "I", "Save");
        if (CommonUtil.isNotEmpty(startDate)) {
            mrWpr.ge("in_date", startDate);
        }
        if (CommonUtil.isNotEmpty(endDate)) {
            mrWpr.le("in_date", endDate);
        }
        if (CommonUtil.isNotEmpty(patientId)) {
            mrWpr.eq("episode_id", patientId);
        }
        if (CommonUtil.isNotEmpty(deptId)) {
            mrWpr.eq("in_loc_id", deptId);
        }
        if (CommonUtil.isNotEmpty(entityId)) {
            mrWpr.eq("entity_id", entityId);
        }
        List<SdsQcincaseEntity> mrList = sdsQcincaseService.selectList(mrWpr);
        all = mrList.size();
        cur = (double) 0;
        for (SdsQcincaseEntity inCase : mrList) {
            try {
                sdsQcFormShowService.getItemResult(inCase.getId());
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                cur++;
            }
        }
    }

    public void initPortalDataMrList(Map<String, Object> params) {
        //单线程版
        /*List<SdsQcincaseEntity> mrList = sdsQcincaseService.selectMrList(params);
        all = mrList.size();
        cur = (double) 0;
        for (SdsQcincaseEntity inCase : mrList) {
            try {
                sdsQcincaseDataService.updatePortalData(inCase.getId());
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                cur++;
            }
        }*/

        //多线程版
        ExecutorService updatePortalService = Executors.newFixedThreadPool(10);//分析数据线程池
        List<SdsQcincaseEntity> mrList = sdsQcincaseService.selectMrList(params);
        all = mrList.size();
        cur = (double) 0;
        for (SdsQcincaseEntity inCase : mrList) {
            updatePortalService.execute(new UpdatePortalData(inCase.getId()));
        }
        updatePortalService.shutdown();


    }

    /**
     * @ClassName: AnalysisData
     * @Description ：    评估分析病例
     * @Date: 2022年2月24日 上午8:59:07
     * @Author sunyingjie
     * @Version 1.0 DHC
     */
    public class AnalysisData extends Thread {
        private Long patientId;
        private String entityIds;

        public AnalysisData(Long patientId, String entityIds) {
            this.patientId = patientId;
            this.entityIds = entityIds;
        }

        public void run() {
            try {
                //消费
                AnalysisDataMain(patientId, entityIds);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * @Description:
     * @Title: AnalysisDataMain
     * @author: sunyingjie
     * @date:2022年2月24日 下午2:50:44
     */
    public void AnalysisDataMain(Long patientId, String entityIds) throws Exception {
        checkSDByAdm(patientId, entityIds);
        //这个时候处理完一个病例 多线程加锁
        synchronized (cur) {
            cur++;
        }
    }

    public class AnalysisCusData extends Thread {
        private Long patientId;
        private String entityIds;

        public AnalysisCusData(Long patientId, String entityIds) {
            this.patientId = patientId;
            this.entityIds = entityIds;
        }

        public void run() {
            try {
                //消费
                checkSDCustom(patientId, entityIds);
                //这个时候处理完一个病例 多线程加锁
                synchronized (cur1) {
                    cur1++;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }


    /**
     * @ClassName: GetValue
     * @Description ：    获取入组病例表单数据
     * @Date: 2022年2月24日 上午8:59:07
     * @Author sunyingjie
     * @Version 1.0 DHC
     */
    public class GetValue extends Thread {
        private Long inCaseId;

        public GetValue(Long inCaseId) {
            this.inCaseId = inCaseId;
        }

        public void run() {
            try {
                //消费
                GetValueMain(inCaseId);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * @Description:
     * @Title: GetValueMain
     * @author: sunyingjie
     * @date:2022年2月24日 下午2:50:44
     */
    public void GetValueMain(Long inCaseId) throws Exception {
        sdsQcfitemExecresultService.execItemResult(inCaseId);
        //这个时候处理完一个病例 多线程加锁
        synchronized (cur) {
            cur++;
        }
    }

    public class UpdatePortalData extends Thread {
        private Long inCaseId;

        public UpdatePortalData(Long inCaseId) {
            this.inCaseId = inCaseId;
        }

        public void run() {
            try {
                //消费
                UpdatePortalDataMain(inCaseId);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    public void UpdatePortalDataMain(Long inCaseId) throws Exception {
        sdsQcincaseDataService.updatePortalData(inCaseId);
        //这个时候处理完一个病例 多线程加锁
        synchronized (cur) {
            cur++;
        }
    }


    public Map<String, Object> getProcess() {
        Map<String, Object> state = new HashMap<String, Object>();
        if (all == 0) {//没有获取到数据
            state.put("v", "100");//值
            state.put("i", "none");//信息
        } else {
            if (cur < all) {//进行中
                DecimalFormat df = new DecimalFormat("0.00");
                state.put("v", df.format(cur / all * 100));//值
                state.put("i", "doing");//信息
            } else {
                state.put("v", "100");//值
                state.put("i", "done");//信息
            }
        }
        return state;
    }

    /**
     * 针对提交记录，进行自动审核并上报
     */
    public void autoUpload() {
        List<SdsQcincaseEntity> submitList = sdsQcincaseService.selectList(new EntityWrapper<SdsQcincaseEntity>().eq("state", "Submit"));
        for (SdsQcincaseEntity incase : submitList) {
            Long mrListId = incase.getId();

            try {
                // 获取表单数据
                List<SdsQcFormItemDto> formItemList = this.sdsQcFormShowService.getItemInfo(mrListId);
                if (formItemList == null || formItemList.size() == 0) {
                    continue;
                }
                // 组装接口数据
                JSONObject dataJSON = this.sdsQcFormShowService.assembData(formItemList);
                // 上传数据
                Map<String, Object> map = this.sdsQcFormShowService.uploadData(mrListId, dataJSON);
                if (CommonUtil.equals(map.get("code"),"1")) {
                    //上报成功，增加审核记录和上报记录
                    incase.setState("Up");
                    incase.setReportStatus("Up");
                    sdsQcincaseService.updateById(incase);
                    // 增加病例操作日志
                    SdsQcincaseOperlogEntity sdsQcincaseOperlogEntity = new SdsQcincaseOperlogEntity();
                    sdsQcincaseOperlogEntity.setInCaseId(mrListId);
                    sdsQcincaseOperlogEntity.setOperState("Check");
                    sdsQcincaseOperlogEntity.setOperUser("自动审核");
                    sdsQcincaseOperlogEntity.setOperDate(new Date());
                    sdsQcincaseOperlogEntity.insert();
                    sdsQcincaseOperlogEntity = new SdsQcincaseOperlogEntity();
                    sdsQcincaseOperlogEntity.setInCaseId(mrListId);
                    sdsQcincaseOperlogEntity.setOperState("Up");
                    sdsQcincaseOperlogEntity.setOperUser("自动上报");
                    sdsQcincaseOperlogEntity.setOperDate(new Date());
                    sdsQcincaseOperlogEntity.insert();

                    //如果存在门户数据采集程序，更新维度数据
                    sdsQcincaseDataService.updatePortalData(mrListId);
                } else {
                    // 上报失败，增加退回记录
                    String message = map.get("message").toString();
                    if (message.contains("重复")) {
                        incase.setState("Up");
                        incase.setReportStatus("Up");
                        incase.setReportState(4);
                        incase.setReportDate(DateUtil.getDateByDay(new DateTime(), 1));
                        incase.setReportMsg("已存在重复数据");
                        sdsQcincaseService.updateById(incase);
                        // 增加病例操作日志
                        SdsQcincaseOperlogEntity sdsQcincaseOperlogEntity = new SdsQcincaseOperlogEntity();
                        sdsQcincaseOperlogEntity.setInCaseId(mrListId);
                        sdsQcincaseOperlogEntity.setOperState("Check");
                        sdsQcincaseOperlogEntity.setOperUser("自动审核");
                        sdsQcincaseOperlogEntity.setOperDate(new Date());
                        sdsQcincaseOperlogEntity.insert();
                        sdsQcincaseOperlogEntity = new SdsQcincaseOperlogEntity();
                        sdsQcincaseOperlogEntity.setInCaseId(mrListId);
                        sdsQcincaseOperlogEntity.setOperState("Up");
                        sdsQcincaseOperlogEntity.setOperUser("自动上报");
                        sdsQcincaseOperlogEntity.setOperDate(new Date());
                        sdsQcincaseOperlogEntity.insert();
                    } else {
                        incase.setState("Back");
                        incase.setFillingStatus("Save");
                        sdsQcincaseService.updateById(incase);
                        // 增加病例操作日志
                        SdsQcincaseOperlogEntity sdsQcincaseOperlogEntity = new SdsQcincaseOperlogEntity();
                        sdsQcincaseOperlogEntity.setInCaseId(mrListId);
                        sdsQcincaseOperlogEntity.setOperState("Back");
                        sdsQcincaseOperlogEntity.setOperResume(message);
                        sdsQcincaseOperlogEntity.setOperUser("自动退回");
                        sdsQcincaseOperlogEntity.setOperDate(new Date());
                        sdsQcincaseOperlogEntity.insert();
                    }
                }
            } catch (Exception e) {
                logger.info(incase.getId() + "：异常错误！");
            }
        }
    }
}
